﻿Imports System.Text
Imports Kairyu.Extension

Namespace Save
    ''' <summary>
    ''' 追加コマンド生成クラス
    ''' </summary>
    ''' <remarks></remarks>
    Friend Class InsertCommandFactory

        Private Shared VALUE_PARAMETER_PREFIX As String = "VP"

        ''' <summary>
        ''' 追加コマンドを生成します。
        ''' </summary>
        ''' <param name="def"></param>
        ''' <param name="trn"></param>
        ''' <param name="prefix"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function Create(ByVal def As SaveDefinition, ByVal trn As IDbTransaction, ByVal prefix As String) As IDbCommand
            Return (New Core).CreateCommand(def, trn, prefix)
        End Function

        Private Class Core

            Private Property Definition As SaveDefinition

            Private Property Command As IDbCommand

            Private Property Prefix As String

            Public Function CreateCommand(ByVal def As SaveDefinition, ByVal trn As IDbTransaction, ByVal prefix As String) As IDbCommand
                Me.Definition = def
                Me.Prefix = prefix

                Me.Command = trn.Connection.CreateCommand
                Me.Command.Transaction = trn

                Me.BuildCommand()

                Return Me.Command
            End Function

            Private Sub BuildCommand()
                Dim columnText As New StringBuilder
                Dim valueText As New StringBuilder
                Dim cnt As Integer = 0

                '値パラメータの追加、生成
                Dim addParameter As Func(Of Object, Type, String) =
                    Function(val As Object, t As Type) As String
                        Dim prm As IDbDataParameter = Me.Command.CreateParameter
                        If t.FullName = "System.Byte[]" Then prm.DbType = DbType.Binary
                        prm.ParameterName = InsertCommandFactory.VALUE_PARAMETER_PREFIX & cnt
                        prm.Value = If(val Is Nothing, DBNull.Value, val)
                        Me.Command.Parameters.Add(prm)
                        cnt += 1
                        Return Me.Prefix & prm.ParameterName
                    End Function

                'コマンド文字列（列）の追加
                Dim addColumnCommand As Action(Of String) =
                    Sub(text As String)
                        columnText.Appenddelimiter(", ")
                        columnText.Append(text)
                    End Sub

                'コマンド文字列（値）の追加
                Dim addValueCommand As Action(Of String) =
                    Sub(text As String)
                        valueText.AppendDelimiter(", ")
                        valueText.Append(text)
                    End Sub

                '列属性に更新値の作成を作成させる
                'For Each item In (From el In Me.Definition.TableAttribute.SuperRelations Select el.YourColumn)
                '    item.BuildInsertColumnCommand(Me.Definition.Model, addColumnCommand, addValueCommand, addParameter)
                'Next
                For Each item As ColumnAttribute In (From el In Me.Definition.TableAttribute.Columns Order By If(el.IsPrimaryKey, 0, 1))
                    item.BuildInsertColumnCommand(Me.Definition.Model, addColumnCommand, addValueCommand, addParameter)
                Next

                Me.Command.CommandText &= String.Format("INSERT INTO {0} ({1}) VALUES ({2})", Me.Definition.TableAttribute.TableFullName, columnText.ToString, valueText.ToString)
            End Sub
        End Class

    End Class

End Namespace

